package org.opentcs.kcvehicle.communication.kc.common;


import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import java.util.Arrays;
import java.util.Collection;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import org.opentcs.kcvehicle.communication.kc.common.byteutils.ByteUtils;
//import org.opentcs.kcvehicle.communication.kc.common.byteutils.ByteUtils;

public class CaffeineUtil {

  /**
   * 缓存的最大容量
   */
  private static final int MAXIMUM_SIZE = 1000;

  /**
   * 缓存项的写入后过期时间
   */
  private static final int EXPIRE_AFTER_WRITE_DURATION = 10;

  /**
   * 过期时间单位（分钟）
   */
  private static final TimeUnit EXPIRE_AFTER_WRITE_TIMEUNIT = TimeUnit.MINUTES;

  private static Cache<String, Object> cache;
  private static Cache<String, AtomicInteger> cacheUUID;

  /**
   * 初始化Caffeine缓存配置
   */
  static {
    //todo  https://github.com/ben-manes/caffeine/wiki 研究一下，然后升级一下版本
    cache = Caffeine.newBuilder()
        .maximumSize(MAXIMUM_SIZE)
        .expireAfterWrite(EXPIRE_AFTER_WRITE_DURATION, EXPIRE_AFTER_WRITE_TIMEUNIT)
        .build();

    cacheUUID = Caffeine.newBuilder()
        .maximumSize(10)
        .expireAfterWrite(Long.MAX_VALUE, EXPIRE_AFTER_WRITE_TIMEUNIT)
        .build();
  }

  public static void main(String[] args) {
    byte[] a = getUUID();
    byte[] b = getUUID();
    byte[] d = ByteUtils.intToBytes(300);
    byte[] c = ByteUtils.intToBytes(32000);
    //todo int 转两个字节长度
    System.out.println(Arrays.asList(getUUID()));

  }


  public static synchronized byte[] getUUID() {
    AtomicInteger uuid = cacheUUID.getIfPresent("UUID");
    if (uuid == null) {
      //transationId 从1 开始，0留给心跳变量，这样就固定报文了
      cacheUUID.put("UUID", new AtomicInteger(1));
      return ByteUtils.intToBytes(1);
    }
    else {
      if (uuid.get() >= 32000) {
        cacheUUID.put("UUID", new AtomicInteger(1));
        return ByteUtils.intToBytes(1);
      }
      else {
        return ByteUtils.intToBytes(uuid.incrementAndGet());
      }
    }
  }

  public static synchronized byte[] getUUIDAGV() {
    AtomicInteger agvuuid = cacheUUID.getIfPresent("AGVUUID");
    if (agvuuid == null) {
      //transationId 从1 开始，0留给心跳变量，这样就固定报文了
      cacheUUID.put("AGVUUID", new AtomicInteger(1));
      return ByteUtils.intToBytesS(1);
    }
    else {
      if (agvuuid.get() >= 32000) {
        cacheUUID.put("AGVUUID", new AtomicInteger(1));
        return ByteUtils.intToBytesS(1);
      }
      else {
        return ByteUtils.intToBytesS(agvuuid.incrementAndGet());
      }
    }
  }

  /**
   * 获取缓存值
   *
   * @param key 缓存键
   * @return 缓存值
   */
  public static Object get(String key) {
    return cache.getIfPresent(key);
  }

  /**
   * 设置缓存值
   *
   * @param key 缓存键
   * @param value 缓存值
   */
  public static void put(String key, Object value) {
    cache.put(key, value);
  }

  /**
   * 移除缓存项
   *
   * @param key 缓存键
   */
  public static void remove(String key) {
    cache.invalidate(key);
  }

  /**
   * 清空缓存
   */
  public static void clear() {
    cache.invalidateAll();
  }

  /**
   * 获取缓存中的所有值
   *
   * @return 缓存中的所有值集合
   */
  public static Collection<Object> getAllValues() {
    return cache.asMap().values();
  }

  /**
   * 清空缓存中的所有值
   */
  public static void removeAllValues() {
    cache.invalidateAll();
  }
}
